/*
 *  Arrow
 *
 *  Created by David Giovannini on 1/5/07.
 *  Copyright 2007 Software by Jove. All rights reserved.
 *
 */
 
#ifndef SBJ_Arrow_PublicationMgr_h
#define SBJ_Arrow_PublicationMgr_h

#include "SBJ/Arrow/Publication.h"
#include "SBJ/Interfaces/IExceptionObserver.h"

#include <boost/thread/mutex.hpp>
#include <boost/noncopyable.hpp>

#include <hash_map>

namespace SBJ
{

namespace Arrow
{

class PublicationMgr : public boost::noncopyable
{
public:
	PublicationMgr( const IExceptionObserver::Ptr& excObserver = IExceptionObserver::Ptr() );
	
	~PublicationMgr( void );

	template < typename MsgType >
	Publication& publish( const std::string& pubKey = std::string() );

	template < typename MsgType, typename Allocator >
	Publication& publishWithAlloc( const Allocator& allocator, const std::string& pubKey = std::string() );

	template < typename MsgType >
	Topic makeTopic( const std::string& topicKey );
		
	// Assumes a single message type in publication
	Topic makeTopic( const std::string& pubKey, const std::string& topicKey );

	template < typename MsgType >
	Topic getTopic( const std::string& topicKey = std::string() ) const;
	
	// Assumes a single message type in publication
	Topic getTopic( const std::string& pubKey, const std::string& topicKey = std::string() ) const;
	
private:
	typedef stdext::hash_map< std::string, Publication* > KeyedPublications;
	
	template < typename MsgType >
	Publication& addPublication( const std::string& pubKey );

	Publication* findPublication( const std::string& pubKey ) const;

	template < typename MsgType >
	Publication* findPublication( void ) const;

	IExceptionObserver::Ptr m_excObserver;
	mutable boost::mutex m_publicationGuard;
	KeyedPublications m_publications;;
};

}

}

#include "PublicationMgr.inl"

#endif